package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


@Log4j2
@Service(value = "UPDATE_TIME_GRADE_RULE")
public class UpdateTimeGradeRuleInterceptor extends GradeRuleInterceptorAdapter {

    private TicketRule rule;
    private List<UpdateTimeParam> params;

    @Override
    public void prepare(TicketRule rule) {
        this.rule = rule;
        params = this.objectMapper.convertValue(rule.getParams(), new TypeReference<List<UpdateTimeParam>>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        AtomicInteger order = new AtomicInteger();
        params.stream().filter(item -> item.isSelected())
                .filter(item -> !ObjectUtils.isEmpty(item.getHours()))
                .filter(item -> ticket.getUpdatedTime().isBefore(LocalDateTime.now().minusHours(item.getHours())))
                .forEach(item -> order.addAndGet(item.getPoints()));

        Duration duration = Duration.between(ticket.getUpdatedTime(), LocalDateTime.now()).abs();
        String ticketHours = String.format("%.2f", (float) duration.toMinutes() / 60);

        ObjectNode orderDetailNode = ticket.getOrderDetail() == null ? this.objectMapper.createObjectNode() : ticket.getOrderDetail().deepCopy();
        ObjectNode itemsNode = this.objectMapper.createObjectNode();
        itemsNode.put("updateTime", ticket.getUpdatedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        itemsNode.put("detail", ticketHours + " hours/" + order.get());
        itemsNode.put("time", ticketHours);
        itemsNode.put("point", order.get());
        orderDetailNode.set("updateTime", itemsNode);
        ticket.setOrderDetail(orderDetailNode);
        ticket.setOrder(ticket.getOrder() + order.get());
    }

    @Data
    private static class UpdateTimeParam {
        private String title;
        private Integer points;
        private Integer hours;
        private boolean selected;
    }

}
